package RayTracing;

import java.util.ArrayList;

public class Ellipsoid implements Shape{

	//########################## Global Variables ###################################
	public double[] center = new double[3];
	public double[][] transMatrix = new double[3][3];
	public double[][] tranposeInvTransMatrix;

	
	public double[][] invTransMatrix = new double[3][3];
	
	public int mtlIndex;
	public Sphere sph;
	public Ray transRay = new Ray();
	
	//########################## Constructors ###################################
	public Ellipsoid(){
		if (RayTracer.SHOW_LOG){ System.out.println("In Ellipsoid Empty Constructor");}
	}

	public Ellipsoid(String[] args){
		if (RayTracer.SHOW_LOG){ System.out.println("In Ellipsoid Constructor");}
		
		center[0] = Double.parseDouble(args[0]);
		center[1] = Double.parseDouble(args[1]);
		center[2] = Double.parseDouble(args[2]);
		
		for (int i = 0 ; i < 3; i ++){
			for (int j = 0; j < 3; j++){
				transMatrix[i][j] = Double.parseDouble(args[3 + j + i*3]);
			}
		}

		
		
		Matrix transMatrixClass = new Matrix(transMatrix);
		Matrix invTransMatrixClass = transMatrixClass.inverse(transMatrixClass);
		invTransMatrix = invTransMatrixClass.getData();
		
		tranposeInvTransMatrix = Vector.transposeMatrix(invTransMatrix);
		
		mtlIndex = Integer.parseInt(args[12]);
		
		int radius = 1;
		double[] tranCenter = Vector.multiplyMatrixVector(transMatrix, center);
		
		sph = new Sphere(tranCenter , radius, mtlIndex);
		
	}
	
	//########################## Shape Functions ###################################
	@Override
	public double[] getColor(Material mtl, Ray r, ArrayList<Lights> lgtList) {
		Sphere sph = getSph();
		double[] position = Vector.multiplyMatrixVector(transMatrix, r.getP());
		double[] N = Vector.createNormalizedVectorv(sph.getCenter(), position);

		
		return RayTracer.GlobalGetColor(mtl, r, lgtList, N);
	}

	@Override
	public double getT(Ray ray) {
		
		transRay.setP0(Vector.multiplyMatrixVector(transMatrix, ray.getP0()));
		double[] newV = Vector.multiplyMatrixVector(transMatrix, ray.getV());
		transRay.setV(Vector.createNormalizedVectorv(newV));
		
		//return sph.getT(transRay);
		double t = sph.getT(transRay);
		if (t < 0)
			return t;

		
		transRay.setT(t);
		double[] interSectionPoint = transRay.getP();
		interSectionPoint = Vector.multiplyMatrixVector(invTransMatrix, interSectionPoint);
		double[] origin = Vector.multiplyMatrixVector(invTransMatrix, transRay.getP0());
		t = Vector.createNorm(origin, interSectionPoint);
		
				
		return t;

	}
	
	//########################## Getters and Setters ###################################
	
	public double[] getCenter() {
		return center;
	}

	public void setCenter(double[] center) {
		this.center = center;
	}

	public double[][] getTransMatrix() {
		return transMatrix;
	}

	public void setTransMatrix(double[][] transMatrix) {
		this.transMatrix = transMatrix;
	}

	public int getMtlIndex() {
		return mtlIndex;
	}

	public void setMtlIndex(int mtlIndex) {
		this.mtlIndex = mtlIndex;
	}

	public Sphere getSph() {
		return sph;
	}

	public void setSph(Sphere sph) {
		this.sph = sph;
	}

	public Ray getTransRay() {
		return transRay;
	}

	public void setTransRay(Ray transRay) {
		this.transRay = transRay;
	}


}
